package com.raymond.client.session;

import com.raymond.client.config.ClientSocketConfig;
import com.raymond.client.connector.IConnector;

import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

/**
 * @author :  raymond
 * @version :  V1.0
 * @date :  2022-10-27 18:03
 */
public abstract class AbstractClientSessionManager implements SessionManager {

    /**
     * 连接器，负责创建连接
     */
    protected IConnector connector;

    private final ConcurrentHashMap<String, AbstractClientSession> channelSessions = new ConcurrentHashMap<>();

    public AbstractClientSessionManager(IConnector connector) {
        this.connector = connector;
    }

    public void addSession(String name, AbstractClientSession session) {
        if (channelSessions.containsKey(name)) {
            throw new RuntimeException("当前name已存在，name" + name);
        }
        for (Map.Entry<String, AbstractClientSession> sessionEntry : channelSessions.entrySet()) {
            if (sessionEntry.getValue().equals(session)) {
                throw new RuntimeException("当前session已存在，name" + sessionEntry.getKey());
            }
        }
        channelSessions.put(name, session);
    }


    @Override
    public AbstractClientSession getChannelSession(String name) {
        if (channelSessions.containsKey(name)) {
            return channelSessions.get(name);
        }
        return null;
    }



    @Override
    public AbstractClientSession createSession(String name, ClientSocketConfig socketConfig) {
        AbstractClientSession clientSession = createSession(socketConfig);
        addSession(name, clientSession);
        return clientSession;
    }

    /**
     * 创建session
     * @param socketConfig 连接配置
     * @return
     */
    protected abstract AbstractClientSession createSession(ClientSocketConfig socketConfig);


    @Override
    public IConnector getConnector() {
        return connector;
    }

    @Override
    public void shutdown(String name) throws InterruptedException {
        AbstractClientSession clientSession = channelSessions.get(name);
        if (clientSession == null) {
            throw new NullPointerException("不存在这个session, name:" + name);
        }
        clientSession.shutdown();
        channelSessions.remove(name);
    }

    @Override
    public void shutdown(AbstractClientSession session) throws InterruptedException {
        for (Map.Entry<String, AbstractClientSession> sessionEntry : channelSessions.entrySet()) {
            if (sessionEntry.getValue().equals(session)) {
                session.shutdown();
                channelSessions.remove(sessionEntry.getKey());
            }
        }
    }

    @Override
    public void destroy() throws InterruptedException {
        for (Map.Entry<String, AbstractClientSession> sessionEntry : channelSessions.entrySet()) {
            sessionEntry.getValue().shutdown();
            channelSessions.remove(sessionEntry.getKey());
        }
        connector.destroy();
        connector = null;
    }
}
